package cn.ghx.xboot.item;

import cn.ghx.xboot.attach.Attachment;
import cn.ghx.xboot.brand.BrandService;
import cn.ghx.xboot.item.fav.ItemFavUserService;
import cn.ghx.xboot.store.Store;
import cn.ghx.xboot.store.StoreService;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ghx.xboot.mapper.ItemMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @author ghx
 * @createDate 2024-03-08 10:46:26
 */
@Service
public class ItemService extends ServiceImpl<ItemMapper, Item> {

    private final StoreService storeService;
    private final ItemFavUserService itemFavUserService;
    private final BrandService brandService;

    @Lazy
    public ItemService(StoreService storeService, ItemFavUserService itemFavUserService, BrandService brandService) {
        this.storeService = storeService;
        this.itemFavUserService = itemFavUserService;
        this.brandService = brandService;
    }

    public Page<Item> query(String keyword,
                            Boolean enabled,
                            Integer page, Integer size) {
        LambdaQueryChainWrapper<Item> qw = lambdaQuery();
        // 参数
        if (StringUtils.hasText(keyword)) {
            qw.and(w -> {
                w.like(Item::getName, keyword).or()
                        .like(Item::getRemark, keyword);
            });
        }
        if (enabled != null) {
            qw.eq(Item::getEnabled, enabled);
        }
        qw.orderByDesc(Item::getCreateTime);
        Page<Item> rs = qw.page(Page.of(page, size));
        rs.getRecords().forEach(this::wrapExtra);
        return rs;
    }

    public Boolean saveItem(Item item) {
        boolean rs = saveOrUpdate(item);
        List<Attachment> medias = item.getMedias();
        if (medias != null && !medias.isEmpty()) {
            String itemId = item.getId();
            removeMedias(itemId);
            saveMedias(itemId, medias.stream().map(Attachment::getId).toList());
        }
        return rs;
    }

    private boolean saveMedias(String itemId, List<String> attIds) {
        return baseMapper.saveMedias(itemId, attIds);
    }

    private boolean removeMedias(String id) {
        return baseMapper.removeMedias(id);
    }

    @Cacheable(value = "ItemService.detail", unless="#result == null")
    public Item detail(String id) {
        return detail(id,null);
    }

    @Cacheable(value = "ItemService.detail2", unless="#result == null")
    public Item detail(String id, String openid) {
        Item rs = getById(id);
        Assert.notNull(rs, "机源信息不存在");
        Assert.isTrue(rs.getEnabled(), "机源已经下架");

        if(StringUtils.hasText(openid)){
            rs.setFav(itemFavUserService.isFav(id,openid));
        }

        return wrapExtra(rs);
    }

    public Item wrapExtra(Item item) {

        item.setBrand(brandService.getById(item.getBrandId()));
        item.setStore(storeService.findById(item.getStoreId()));
        item.setMedias(getMedias(item.getId()));
        return item;
    }

    private List<Attachment> getMedias(String id) {
        return baseMapper.getMedias(id);
    }


    public Page<Item> query(
            String keyword,
            String brandId,
            String storeId,
            Float tonnageStart,
            Float tonnageEnd,
            Float priceStart,
            Float priceEnd,
            Integer hourStart,
            Integer hourEnd,
            Boolean rentable,
            String province,
            Integer page,
            Integer size,
            String sort
    ) {
        Page<Item> pagi = Page.of(page, size);
        Page<Item> rs = baseMapper.query(keyword, brandId, storeId, tonnageStart, tonnageEnd, priceStart, priceEnd, hourStart, hourEnd, rentable,
                province,
                sort, pagi);
        rs.getRecords().forEach(this::wrapExtra);
        return rs;
    }

    /**
     * 获取推荐的机源信息
     *
     * @param originId 推荐的依据的机源ID
     * @param size     获取多少个
     * @return
     */
    public List<Item> getRecommend(String originId, Integer size) {
        List<Item> rs = baseMapper.getRecommend(originId, size);

        rs.forEach(this::wrapExtra);

        return rs;
    }

    @CacheEvict(value = {"ItemService.detail","ItemService.detail2"},allEntries = true)
    public Boolean remove(String id) {
        return removeById(id);
    }

    public Long countByStoreId(String id) {
        return lambdaQuery().eq(Item::getStoreId, id).eq(Item::getEnabled, true).count();
    }
}




